#!/bin/sh
#(c) Copyright 2005 Barry Kauler www.goosee.com/puppy
#2007 Lesser GPL licence v2 (http://www.fsf.org/licensing/licenses/lgpl.html)
#pup up to 1.0.3 only used Xvesa Kdrive server.
#v1.0.4 introduces framebuffer Xfbdev Kdriver server, choice
#at first bootup.

PSFND="`ps`"
MSGWIN="WARNING: CHOOSING \"YES\" WILL CAUSE IMMEDIATE REBOOT!"
if [ ! "`echo -n "$PSFND" | grep "/bin/xwin"`" = "" ];then
 MSGWIN="PLEASE CLOSE ALL OTHER WINDOWS BEFORE CHOOSE \"YES\"!
DO THAT RIGHT NOW IF YOU ARE GOING TO CHOOSE THE \"YES\" OPTION!"
fi
MSGFB="
CURRENT STATUS:
The Xfbdev Kdrive framebuffer X server is currently not running.
"
if [ "`readlink /usr/X11R7/bin/X`" = "Xfbdev"  ];then
 MSGFB="
CURRENT STATUS:
The Xfbdev Kdrive framebuffer X server is currently running,
and the video setting currently is:
 `cat /etc/videofb`
"
fi
if [ "`readlink /usr/X11R7/bin/X`" = "Xvesa"  ];then
 MSGFB="
The Xfbdev Kdrive framebuffer X server is currently not running.
The Xvesa Kdrive X server is now running.
To keep the current situation, select \"No\" button.
To adjust Xvesa settings, run the Xvesa Video Wizard.
"
fi

#will call this script from /etc/rc.d/rc.local0, after /usr is loaded,
#as this script and modinfo are both in /usr/sbin/.
#rc.local0 appends "boot" on the commandline...
if [ ! "$1" = "boot" ];then
 if [ ! -f /usr/X11R7/bin/Xfbdev ];then #precaution.
  dialog --title "Xfbdev Video Wizard" --msgbox "Sorry, this build of Puppy does not
have the Xfbdev Kdrive X server.

Press ENTER key to exit..." 0 0
  exit
 fi
 dialog --title "Xfbdev Video Wizard" --yesno "Welcome to the Framebuffer Wizard!
Puppy has two different Kdrive X servers, Xvesa and Xfbdev.
Xvesa is the default and works on most PCs. Xfbdev may work
on some video hardware that Xvesa does not work properly on,
also Xfbdev allows adjustment of the screen refresh frequency.

The Framebuffer Wizard can only make changes at bootup, so if
you answer \"Yes\" here, the PC will reboot immediately and the
Wizard will run.
$MSGFB
$MSGWIN
Press ENTER key while \"Yes\" highlighted (for immediate reboot)
otherwise TAB or RIGHT-ARROW to highlight \"No\" then ENTER..." 0 0
 if [ $? -eq 0 ];then
  #rm -f /usr/X11R7/bin/X
  echo -n "1" > /root/.fbbootflag
  sync
  if [ "`echo -n "$PSFND" | grep "/bin/xwin"`" = "" ];then
   exec reboot #running without X.
  else
   exec /usr/X11R7/bin/fvwmreboot #a window manager is running.
  fi
 fi
 exit
fi
#did pass "boot" param, so continuing...


loadfbfunc() {
 case $VIDEOMODULE in
  sisfb)
   MODEXEC="modprobe sisfb mode=$RESXYB rate=$FBRATE"
   modprobe sisfb mode=$RESXYB rate=$FBRATE 2> /tmp/fbmnterr.txt
   RETVAL=$?
   ;;
  tridentfb)
   MODEXEC="modprobe tridentfb mode=$RESXYN bpp=$RESBPP"
   modprobe tridentfb mode=$RESXYN bpp=$RESBPP 2> /tmp/fbmnterr.txt
   RETVAL=$?
   ;;
  intelfb)
   MODEXEC="modprobe intelfb mode=${RESXYN}-${RESBPP}@${FBRATE} accel=1 mtrr=1"
   modprobe intelfb mode=${RESXYN}\-${RESBPP}@${FBRATE} accel=1 mtrr=1 2> /tmp/fbmnterr.txt
   RETVAL=$?
   ;;
  neofb)
   MODEXEC='modprobe neofb #note, no params.'
   modprobe neofb  2> /tmp/fbmnterr.txt #note, no params?
   RETVAL=$?
   ;;
  rivafb)
   MODEXEC='modprobe rivafb #note, no params.'
   modprobe rivafb  2> /tmp/fbmnterr.txt #note, no params?
   RETVAL=$?
   ;;
 esac
}

#just use the existing configuration if /root/.fbbootflag=0...
if [ ! -f /root/.fbbootflag ];then
 echo -n "1" > /root/.fbbootflag
fi
if [ "`cat /root/.fbbootflag`" = "0" ];then
 if [ "`readlink /usr/X11R7/bin/X`" = "Xfbdev"  ];then
  if [ -f /etc/videofb ];then #precaution
   VIDEOFB="`cat /etc/videofb`"
   VIDEOMODULE="`echo -n "$VIDEOFB" | tr " " "\n" | grep "module=" | cut -f 2 -d '='`"
   FBRATE="`echo -n "$VIDEOFB" | tr " " "\n" | grep "rate=" | cut -f 2 -d '='`"
   RESXYB="`echo -n "$VIDEOFB" | tr " " "\n" | grep "mode=" | cut -f 2 -d '='`"
   FBMEM="`echo -n "$VIDEOFB" | tr " " "\n" | grep "mem=" | cut -f 2 -d '='`"
   RESXYN="`echo -n "$RESXYB" | cut -f 1-2 -d 'x'`"
   RESBPP="`echo -n "$RESXYB" | cut -f 3 -d 'x'`"
   loadfbfunc
   sleep 1
   if [ ! $RETVAL -eq 0 ];then
    ln -sf Xvesa /usr/X11R7/bin/X
   fi
  else #precaution
   ln -sf Xvesa /usr/X11R7/bin/X
  fi
 else
  #well, do not need the fb modules...
  rm -rf /lib/modules/2.4/video/*/*fb.* 2> /dev/null
  rm -rf /lib/modules/2.4/video/*fb.* 2> /dev/null
  rm -rf /lib/modules/2.6/video/*/*fb.* 2> /dev/null
  rm -rf /lib/modules/2.6/video/*fb.* 2> /dev/null
 fi
 exit #use Xvesa, or whatever X points to.
fi


###############################################
#okay, this is the wizard part of the script...

if [ -f /usr/X11R7/bin/Xvesa ];then
 Xvesa -listmodes > /tmp/Xmodes.txt 2>&1
else
 echo -n "" > /tmp/Xmodes.txt
fi

FBMODE=""
MSG0=""
FBMODE="1024x768x16"
FBMODULE=""
FBMEM=""
VIDEOFB=""
if [ -f /etc/videofb ];then
 VIDEOFB="`cat /etc/videofb`"
 FBMODULE="`echo -n "$VIDEOFB" | tr " " "\n" | grep "module=" | cut -f 2 -d '='`"
 FBRATE="`echo -n "$VIDEOFB" | tr " " "\n" | grep "rate=" | cut -f 2 -d '='`"
 FBMODE="`echo -n "$VIDEOFB" | tr " " "\n" | grep "mode=" | cut -f 2 -d '='`"
 FBMEM="`echo -n "$VIDEOFB" | tr " " "\n" | grep "mem=" | cut -f 2 -d '='`"
 #MSG0="(Note, your last choice was the $FBMODULE module)
 MSG0="(Previous: $VIDEOFB)
"
fi
if [ ! "$FBRATE" ];then
 FBRATE="60"
fi

#VIDEOINFO="`cat /proc/pci | grep --ignore-case --extended-regexp "vga|video"`"
VIDEOINFO="`cat /proc/pci | grep "VGA" | cut -f 2-4 -d ':'`"
VIDEOMODULE=""

if [ ! "`echo "$VIDEOINFO" | grep "SiS"`" = "" ];then
 VIDEOCHIP="SiS"
 VIDEOMODULE="sisfb"
 #FBDESCRIPTION="SiS 300/540/630/730/315/550/65x/661/74x/330/760 framebuffer device"
fi
if [ ! "`echo "$VIDEOINFO" | grep "Trident"`" = "" ];then
 VIDEOCHIP="Trident"
 VIDEOMODULE="tridentfb"
 #FBDESCRIPTION="Framebuffer driver for Trident cards"
fi
if [ ! "`echo "$VIDEOINFO" | grep "Intel"`" = "" ];then
 VIDEOCHIP="Intel"
 VIDEOMODULE="intelfb"
 #FBDESCRIPTION="Framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G chipset"
fi
if [ ! "`echo "$VIDEOINFO" | grep -i "NeoMagic"`" = "" ];then
 VIDEOCHIP="NeoMagic"
 VIDEOMODULE="neofb"
fi
if [ ! "`echo "$VIDEOINFO" | grep -i "nVidia"`" = "" ];then
 VIDEOCHIP="nVidia"
 VIDEOMODULE="rivafb"
fi

if [ -f /usr/X11R7/bin/Xvesa ];then
 MSGXVESA=" Puppy will default to using the Xvesa Kdrive X server,
 which works on most PCs and is usually best choice."
 DEFLABEL="Xvesa"
else
 MSGXVESA=" Puppy would like to fall back to the Xvesa Kdrive X server,
 but it is not installed. So, cannot run X with Xvesa."
 DEFLABEL="Default"
fi

#okay to run modinfo as /usr/sbin is available...
FBDESCRIPTION="`modinfo $VIDEOMODULE | grep "description:" | cut -f 2-4 -d ':' | cut -b 1-68`"

if [ "$VIDEOMODULE" ];then
 MSG1="Your PC has a $VIDEOCHIP video chip, described as:
 $VIDEOINFO
The $VIDEOMODULE framebuffer driver module description:
 $FBDESCRIPTION
...so perhaps will work with your video chip?
$MSG0
If you just press the ENTER key, Puppy will default to not using
a framebuffer driver and the default will be:
$MSGXVESA

Note: you can try both. Choose the default now maybe, later you
will be able to run the Video Wizard and make a different choice.

Press ENTER key while \"${DEFLABEL}\" highlighted for default, else TAB or
ARROW-KEY to highlight \"Framebuffer\" then ENTER for framebuffer..."
else
 #framebuffer option not currently supported.
 dialog --title "Xfbdev Video Wizard" --msgbox "This version of Puppy does not seem to have any suitable
kernel framebuffer driver module for the video hardware.
So, defaulting to:
$MSGXVESA

Press ENTER key to continue..."
 rm -f /etc/videofb
 if [ -f /usr/X11R7/bin/Xvesa ];then
  ln -sf Xvesa /usr/X11R7/bin/X #precaution.
 fi
 #to prevent wizard from running in setup mode at next entry...
 echo -n "0" > /root/.fbbootflag #precaution.
 #well, do not need the fb modules...
 rm -rf /lib/modules/2.4/video/*/*fb.* 2> /dev/null
 rm -rf /lib/modules/2.4/video/*fb.* 2> /dev/null
 rm -rf /lib/modules/2.6/video/*/*fb.* 2> /dev/null
 rm -rf /lib/modules/2.6/video/*fb.* 2> /dev/null
 exit
fi

dialog --title "Xfbdev Video Wizard" --yes-label "$DEFLABEL" --no-label "Framebuffer" --yesno "$MSG1" 0 0
if [ $? -eq 0 ];then
 #rm -f /etc/videofb
 if [ -f /usr/X11R7/bin/Xvesa ];then
  ln -sf Xvesa /usr/X11R7/bin/X
 fi
 #to prevent wizard from running in setup mode at next entry...
 echo -n "0" > /root/.fbbootflag
 #well, do not need the fb modules...
 rm -rf /lib/modules/2.4/video/*/*fb.* 2> /dev/null
 rm -rf /lib/modules/2.4/video/*fb.* 2> /dev/null
 rm -rf /lib/modules/2.6/video/*/*fb.* 2> /dev/null
 rm -rf /lib/modules/2.6/video/*fb.* 2> /dev/null
 exit
fi

ALLVIDCHOICES="640x480x16
640x480x24
800x600x16
800x600x24
1024x768x16
1024x768x24
1280x960x16
1280x1024x16
1280x1024x24
1600x1200x16
1600x1200x24
1920x1440x16
1920x1440x24"

VIDEOCHOICES="`cat /tmp/Xmodes.txt | grep --extended-regexp "640x480x16|640x480x24|800x600x16|800x600x24|1024x768x16|1024x768x24|1280x960x16|1280x1024x16|1280x1024x24|1600x1200x16|1600x1200x24|1920x1440x16|1920x1440x24" | tr ':' ' ' | tr -s ' ' | cut -f 2 -d " " | sort`"
NEWCHOICES="`echo -n "$VIDEOCHOICES" | grep -v "$FBMODE" | tr "\n" "V" | sed -e 's/V/_supported off V/g' | tr "V" "\n"`"
OLDCHOICE=""
if [ "$FBMODE" ];then
 if [ "`echo -n "$VIDEOCHOICES" | grep "$FBMODE"`" = "" ];then
  OLDCHOICE="${FBMODE}_unknown on 
"
 else
  OLDCHOICE="${FBMODE}_supported on 
"
 fi
fi

#find unsupported modes...
#and insert column 1 with a tag number...
BADCHOICES=""
FINALCHOICES=""
for ONEMODE in `echo -n "$ALLVIDCHOICES" | tr "\n" " "`
do
 TAGCNT="$ONEMODE"
 if [ "`echo -n "$OLDCHOICE$NEWCHOICES" | grep "$ONEMODE"`" = "" ];then
  FINALCHOICES="${FINALCHOICES} ${TAGCNT} ${ONEMODE}_unknown off "
 else
  ONEMODE="`echo -n "$OLDCHOICE$NEWCHOICES" | grep "$ONEMODE"`"
  FINALCHOICES="${FINALCHOICES} ${TAGCNT} ${ONEMODE}"
 fi
done


dialog --title "Xfbdev Video Wizard" --radiolist "Please choose a video mode. The format is widthxheightxbits.
Width and height are in pixels, 16/24 bits = 65,536/16,777,216 colors.
Note: _supported means mode confirmed supported by the video card.
      _unknown   will not work with Xvesa but may work with framebuffer.

Use DOWN-ARROW then press SPACEBAR on desired choice then
press ENTER key..." 0 0 0 $FINALCHOICES 2>/tmp/tag.txt

CHOSENTAG="`cat /tmp/tag.txt 2>/dev/null`"
if [ "$CHOSENTAG" ];then
 FBMODE="$CHOSENTAG"
else
 if [ ! "$FBMODE" ];then
  FBMODE="1024x768x16"
 fi
fi


RATES='56 Hertz_for_very_low_quality_monitor
60 Hertz_for_low_quality_monitor_or_high_res
72 Hertz
75 Hertz
85 Hertz
90 Hertz'
NEWRATES="`echo "$RATES" | grep -v "$FBRATE" | tr "\n" "W" | sed -e 's/W/ off /g'`"
OLDRATE="`echo "$FBRATE" | tr "\n" "W" | sed -e 's/W/ Hertz on /g'`"

dialog --title "Xfbdev Video Wizard" --radiolist "You have chosen $FBMODE.
Now you need to choose the screen refresh frequency.
Please be very careful about this -- choosing a higher rate
than your monitor is specified for can damage the monitor.
IF IN DOUBT, CHOOSE 60Hz.
(a really old 14 inch monitor may be limited to 800x600-56)

NOTE: If make wrong choice, there is opportunity to try again.

Use DOWN-ARROW then press SPACEBAR on desired choice then
press ENTER key..." 0 0 0 $OLDRATE$NEWRATES 2>/tmp/tag.txt

CHOSENTAG="`cat /tmp/tag.txt 2>/dev/null`"
if [ "$CHOSENTAG" ];then
 FBRATE="$CHOSENTAG"
fi

#so far we have these. examples:
#VIDEOMODULE="sisfb" FBMODE="0x0117 1024x768x16" FBRATE="60"
#now need to decide on a mem= allocation for each mode.
#1024x768x16 needs 12288K ...maybe we can leave this out, let it auto-assign.

#then compose the /etc/videofb line:
# sisfb mode=1024x768x16 rate=60 mem=12288
#this can be executed as a postfix to modprobe.
RESXYB="`echo -n "$FBMODE" | cut -f 2 -d " "`"
RESXYN="`echo -n "$RESXYB" | cut -f 1-2 -d 'x'`"
RESBPP="`echo -n "$RESXYB" | cut -f 3 -d 'x'`"
if [ -f /etc/videofb ];then
 cp -f /etc/videofb /etc/videofb.old
fi
echo "module=$VIDEOMODULE mode=$RESXYB rate=$FBRATE mem=" > /etc/videofb

dialog --title "Xfbdev Video Wizard" --msgbox "Okay, just about to take the plunge.
Here are the choices you have made:
 `cat /etc/videofb`

If the next screen shows a nice dialog box, like this one, then the
video mode change was successful. If the screen is blank or garbage,
then failure.
If successful, press ENTER key within 30 seconds.
If failure, either hit CTRL-ALT-DEL to cause immediate reboot, or
wait for 30 seconds and timeout will assume failure.

REMEMBER, Garbage screen: CTRL-ALT-DEL or wait 30 second timeout!

Press ENTER key now to switch to new video mode..." 0 0

#load fb module...
loadfbfunc
sleep 3

#if loading of fb modules succeeds, relink /usr/X11R7/bin/X to Xfbdev,
#otherwise to Xvesa.
if [ $RETVAL -eq 0 ];then
 dialog --timeout 30 --title "Xfbdev Video Wizard" --msgbox "Okay, have loaded framebuffer driver with this command:
$MODEXEC
which seems to have been successful.
X graphics mode will run with the Xfbdev Kdrive X server.
NOTE: framebufferwizard can run from the console if X not work.

PLEASE PRESS ENTER KEY WITHIN 30 SECONDS OF THIS WINDOW APPEARING
OTHERWISE FAILURE WILL BE ASSUMED!

Press the ENTER key to continue..." 0 0
 if [ $? -eq 0 ];then
  #works.
  ln -sf Xfbdev /usr/X11R7/bin/X
 else
  #failure
  if [ -f /usr/X11R7/bin/Xvesa ];then
   ln -sf Xvesa /usr/X11R7/bin/X #precaution.
  fi
  sync
  exec reboot
  #...wizard will start again on reboot.
 fi
else
 MSGFIN1=""
 if [ -f /usr/X11R7/bin/Xvesa ];then
  MSGFIN1="Note, if you choose \"Quit\", Puppy will use the Xvesa server.
"
 fi
 dialog --title "Xfbdev Video Wizard" --yes-label "Rerun" --no-label "Quit" --yesno "Attempted to load framebuffer driver with this command:
$MODEXEC
but it was unsuccessful. This is the error message:
`cat /tmp/fbmnterr.txt | head -n 5`

Select \"Rerun\" button to rerun the Framebuffer Wizard and
try again, or \"Quit\" to quit.
$MSGFIN1
NOTE: framebufferwizard can run from the console if X not work." 0 0
 if [ $? -eq 0 ];then
  sync
  exec /usr/sbin/framebufferwizard
  #...exits from script.
 else
  if [ -f /etc/videofb.old ];then
   cp -f /etc/videofb.old /etc/videofb
  fi
  if [ -f /usr/X11R7/bin/Xvesa ];then
   ln -sf Xvesa /usr/X11R7/bin/X #precaution.
  fi
 fi
fi
sync

#to prevent wizard from running in setup mode at next entry...
echo -n "0" > /root/.fbbootflag

#END#
